﻿using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetJsWire.Design.CodeDom
{
    internal sealed class ExpressionTable
    {
        // Fields
        private Hashtable _expressions;

        // Methods
        internal bool ContainsPresetExpression( object value )
        {
            ExpressionInfo info = this.Expressions[ value ] as ExpressionInfo;
            return ( ( info != null ) && info.IsPreset );
        }

        internal CodeExpression GetExpression( object value )
        {
            CodeExpression expression = null;
            ExpressionInfo info = this.Expressions[ value ] as ExpressionInfo;
            if ( info != null )
            {
                expression = info.Expression;
            }
            return expression;
        }

        internal void SetExpression( object value, CodeExpression expression, bool isPreset )
        {
            this.Expressions[ value ] = new ExpressionInfo( expression, isPreset );
        }

        // Properties
        private Hashtable Expressions
        {
            get
            {
                if ( this._expressions == null )
                {
                    this._expressions = new Hashtable( new ReferenceComparer() );
                }
                return this._expressions;
            }
        }

        // Nested Types
        private class ExpressionInfo
        {
            // Fields
            private CodeExpression _expression;
            private bool _isPreset;

            // Methods
            internal ExpressionInfo( CodeExpression expression, bool isPreset )
            {
                this._expression = expression;
                this._isPreset = isPreset;
            }

            // Properties
            internal CodeExpression Expression
            {
                get
                {
                    return this._expression;
                }
            }

            internal bool IsPreset
            {
                get
                {
                    return this._isPreset;
                }
            }
        }

        private class ReferenceComparer : IEqualityComparer
        {
            // Methods
            bool IEqualityComparer.Equals( object x, object y )
            {
                return object.ReferenceEquals( x, y );
            }

            int IEqualityComparer.GetHashCode( object x )
            {
                if ( x != null )
                {
                    return x.GetHashCode();
                }
                return 0;
            }
        }
    }
}
